package com.unnet.yjs.config;

import com.google.common.collect.Lists;
import com.unnet.yjs.base.ContainerProperties;
import com.unnet.yjs.entity.Log;
import com.unnet.yjs.entity.OssFileRecord;
import com.unnet.yjs.service.OssFileRecordService;
import com.unnet.yjs.util.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

/**
 * Email: love1208tt@foxmail.com
 * Copyright (c)  2019. missbe
 *
 * @author lyg   19-7-10 下午7:48
 **/
@Component
@Configuration
@EnableScheduling
public class ScheduleTaskConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleTaskConfig.class);
    @Resource
    private ContainerProperties containerProperties;
    @Resource
    private OssFileRecordService ossFileRecordService;

    //    @Scheduled(cron = "0 0 2 1/7 * ?")
    //    @Scheduled(cron =  "0/40 * * * * ?")
    @Scheduled(cron = "0 */5 * * * ?")
    private void scheduleDeleteFile() {
        Log sysLog = new Log();
        sysLog.setBrowser("Default");
        sysLog.setUsername("OssFileTask");
        sysLog.setType("OssFileTask");
        sysLog.setTitle("OssFileTask");
        long startTime = System.currentTimeMillis();
        LOGGER.info("开始定时删除缓存文件任务，控制文件夹【{}】大小.", containerProperties.getFileCacheLocation());
        long folderSize = getFolderSize();
        long gUnit = 1073741824L;
        String restrictSizeString = containerProperties.getRestrictSize();
        long restrictSize = Long.parseLong(restrictSizeString);
        LOGGER.info("文件夹：【{}】，大小：【{}】，限制大小为：【{}G】", containerProperties.getFileCacheLocation(), FileUtil.formatFileSize(folderSize), restrictSize);
        ///1.删除文件大小为0的文件
        File dir = new File(containerProperties.getFileCacheLocation());
        FileUtil.deleteEmptyFile(dir);

        ///2.删除已经更新的缓存
        List<OssFileRecord> waitDeleteRecords = ossFileRecordService.findWaitDeleteRecord();
        if (!waitDeleteRecords.isEmpty()) {
            boolean deleteSuccess;
            File deleteFile;
            List<Long> ids = Lists.newArrayList();
            for (OssFileRecord ossFileRecord : waitDeleteRecords) {
                deleteFile = new File(containerProperties.getFileCacheLocation() + ossFileRecord.getFileName());
                if (deleteFile.isFile()) {
                    deleteSuccess = deleteFile.delete();
                    if (deleteSuccess) {
                        LOGGER.info("缓存文件[" + deleteFile.getAbsolutePath() + "]删除成功.");
                        ///缓存文件删除成功，删除数组库中的记录
                        ids.add(ossFileRecord.getId());
                    } else {
                        LOGGER.info("缓存文件[" + deleteFile.getAbsolutePath() + "]删除成功.");
                    }
                }
            }
            if (!ids.isEmpty()) {
                ossFileRecordService.deleteBatchIds(ids);
            }
        }


        ///3.如果超出限制进行清理
        restrictSize = restrictSize * gUnit;
        if (restrictSize < folderSize) {
            List<OssFileRecord> ossFileRecords = ossFileRecordService.findAll();
            List<OssFileRecord> waitDeleteRecord = new ArrayList<>();
            ////删除限制大小的一半内容
            restrictSize = restrictSize / 2;
            long totalWaitDeleteSize = 0L;
            for (OssFileRecord record : ossFileRecords) {
                if (totalWaitDeleteSize < restrictSize) {
                    waitDeleteRecord.add(record);
                    totalWaitDeleteSize += Long.parseLong(record.getFileLength());
                }
                ///访问次数清空
                record.setVisitCount(1);
            }///end for
            ///更新记录
            ossFileRecordService.updateBatchById(ossFileRecords);
            File waitDeleteFile;
            StringBuilder builder = new StringBuilder();
            for (OssFileRecord record : waitDeleteRecord) {
                waitDeleteFile = new File(containerProperties.getFileCacheLocation() + record.getFileName());
                boolean isDelete = waitDeleteFile.delete();
                if (isDelete) {
                    LOGGER.info("文件【{}】删除成功.", record);
                } else {
                    builder.append(record);
                    LOGGER.info("文件【{}】删除失败.", record);
                }///end if
            }
            sysLog.setException(builder.toString());
            LOGGER.info("结束定时删除缓存文件任务，此次删除【{}】文件.文件夹剩余大小：{}", FileUtil.formatFileSize(totalWaitDeleteSize), FileUtil.formatFileSize(getFolderSize()));
        } else {
            LOGGER.info("结束定时删除缓存文件任务，文件夹【{}】未超过限定大小.", containerProperties.getFileCacheLocation());
        }
        sysLog.setUseTime(System.currentTimeMillis() - startTime);
        sysLog.setRemoteAddr("127.0.0.1");
        sysLog.setRequestUri("/api/v1/resource/file/video");
        sysLog.setClassMethod(this.getClass().getName());
        sysLog.setHttpMethod("Native");
        ///add sys log
        sysLog.insert();
    }

    private long getFolderSize() {
        String folderPath = containerProperties.getFileCacheLocation();
        File parentDir = new File(folderPath);
        if (!parentDir.exists()) {
            boolean isMakeParentDir = parentDir.mkdirs();
            if (isMakeParentDir) {
                LOGGER.info("创建文件夹{}成功.", parentDir.getAbsolutePath());
            } else {
                LOGGER.error("创建文件夹{}失败.", parentDir.getAbsolutePath());
            }
        }//end if
        return FileUtil.getFileOrFolderSize(parentDir);
    }

}
